package com.github.zzay.auth.controller;

import com.github.zzay.auth.entity.OAuthClientDetails;
import com.github.zzay.auth.service.OAuthClientDetailsService;
import com.github.zzay.common.core.model.ResponseBean;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

/**
 * @author zzay
 * @className OAuthClientDetailsController
 * @description OAuth2 Client Details Controller
 * @create 2022/06/07 23:06
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/client")
@Tag(name = "OAuthClientDetailsController", description = "Oauth2客户端信息管理")
public class OAuthClientDetailsController {

    /**
     * OAuth 客户端 Service 实例
     */
    private final OAuthClientDetailsService oauthClientDetailsService;

    /**
     * 密码编码器
     */
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     * 根据ID获取客户端实体
     *
     * @param id 客户端ID
     * @return 响应的客户端Bean
     */
    @Operation(summary = "获取客户端信息", description = "根据客户端 id 获取客户端详细信息",
            security = @SecurityRequirement(name = HttpHeaders.AUTHORIZATION))
    @Parameter(name = "id", description = "客户端ID", required = true)
    @GetMapping("/getById")
    public ResponseBean<OAuthClientDetails> oauthClient(@PathVariable Long id) {
        OAuthClientDetails oauthClientDetails = null;
        if (id != null) {
            oauthClientDetails = oauthClientDetailsService.getById(id);
        }
        return new ResponseBean(HttpStatus.OK.value(), "Get Client Info", oauthClientDetails);
    }

    /**
     * 创建客户端
     *
     * @param oauthClientDetails 客户端实体
     * @return 包含请求处理结果的响应Bean
     */
    @Operation(summary = "创建客户端", description = "创建客户端",
            security = @SecurityRequirement(name = HttpHeaders.AUTHORIZATION))
    @Parameter(name = "oauthClientDetails", description = "客户端实体oauthClientDetails", required = true)
    @PostMapping("/create")
    public ResponseBean<Boolean> oauthClient(@RequestBody OAuthClientDetails oauthClientDetails) {
        // 加密密钥
        oauthClientDetails.setClientSecret(bCryptPasswordEncoder.encode(oauthClientDetails.getClientSecretPlainText()));
        return new ResponseBean(HttpStatus.OK.value(), "Create Client", oauthClientDetailsService.save(oauthClientDetails));
    }

    /**
     * 修改客户端
     *
     * @param oauthClientDetails 客户端实体
     * @return 包含请求处理结果的响应Bean
     */
    @Operation(summary = "更新客户端信息", description = "根据客户端id更新客户端的基本信息",
            security = @SecurityRequirement(name = HttpHeaders.AUTHORIZATION))
    @Parameter(name = "oauthClientDetails", description = "客户端实体oauthClientDetails", required = true)
    @PutMapping("/update")
    public ResponseBean<Boolean> updateOauthClient(@RequestBody OAuthClientDetails oauthClientDetails) {
        OAuthClientDetails tempOauthClientDetails = oauthClientDetailsService.getById(oauthClientDetails.getClientId());
        // 有调整过明文则重新加密密钥
        if (tempOauthClientDetails != null
                && !tempOauthClientDetails.getClientSecretPlainText().equals(oauthClientDetails.getClientSecretPlainText())) {
            oauthClientDetails.setClientSecret(bCryptPasswordEncoder.encode(oauthClientDetails.getClientSecretPlainText()));
        }
        return new ResponseBean(HttpStatus.OK.value(), "Update Client", oauthClientDetailsService.updateById(oauthClientDetails));
    }

    /**
     * 根据id删除客户端
     *
     * @param oauthClientDetails 客户端实体
     * @return 包含请求处理结果的响应Bean
     */
    @Operation(summary = "删除客户端", description = "根据ID删除客户端",
            security = @SecurityRequirement(name = HttpHeaders.AUTHORIZATION))
    @Parameter(name = "id", description = "客户端ID", required = true)
    @DeleteMapping("/deleteById")
    public ResponseBean<Boolean> deleteOauthClient(@RequestBody OAuthClientDetails oauthClientDetails) {
        OAuthClientDetails oAuthClientDetails = new OAuthClientDetails();
        oauthClientDetails.setClientId(oAuthClientDetails.getClientId());
        return new ResponseBean(HttpStatus.OK.value(), "Delete Client", oauthClientDetailsService.removeById(oauthClientDetails.getClientId()));
    }

}
